feat: Add multi-arch Docker builds and auto-download template inputs#8
feat: Add multi-arch Docker builds and auto-download template inputs#8jamesbrink merged 2 commits intomainfrom
Conversation
Multi-architecture Docker support: - Build CPU images for both amd64 and arm64 (Apple Silicon compatible) - CUDA images remain x86_64 only (NVIDIA requirement) - Use QEMU emulation in CI for cross-architecture builds - Create multi-arch manifests for seamless pulling on any platform - Update README with Apple Silicon Docker instructions Auto-download workflow template input files: - Add template_inputs.sh script to download example images on startup - Fetch manifest from GitHub workflow_templates repository - Non-blocking download (doesn't fail startup if network unavailable) - Cache manifest for 7 days to minimize network requests - Skip existing files for faster subsequent startups - Add curl and jq to runtime PATH via makeWrapper 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Code Review - PR #8: Multi-arch Docker builds and auto-download template inputsOverviewThis PR adds significant enhancements: multi-architecture Docker support (amd64 + arm64) and automatic template input file downloads. Overall, the implementation is well-structured and follows the project's conventions. I've identified several areas for improvement below. 🟢 Strengths1. Architecture & Design
2. Code Quality
3. CI/CD Design
🟡 Issues & Recommendations1. Shellcheck Warning (Minor)Location: Issue: Variable display_name=$(echo "$line" | jq -r '.display_name // empty')Recommendation: Either use it in logging or remove it: log_debug "Downloading: ${display_name:-$filename}"2. Error Handling in Template Download (Medium)Location: Issue: Silent failures with if \! curl -fsSL --connect-timeout 5 --max-time 30 "$TEMPLATE_MANIFEST_URL" -o "$manifest_cache.tmp" 2>/dev/null; then
log_warn "Could not fetch template manifest (network unavailable or timeout)"Recommendation: Capture and log curl's actual error: local curl_error
if \! curl_error=$(curl -fsSL --connect-timeout 5 --max-time 30 "$TEMPLATE_MANIFEST_URL" -o "$manifest_cache.tmp" 2>&1); then
log_warn "Could not fetch template manifest: ${curl_error}"
log_debug "URL: $TEMPLATE_MANIFEST_URL"
return 0
fi3. Race Condition in Manifest Cache (Medium)Location: Issue: Direct mv "$manifest_cache.tmp" "$manifest_cache"Recommendation: Add error checking: if [[ -s "$manifest_cache.tmp" ]]; then
mv "$manifest_cache.tmp" "$manifest_cache"
else
log_warn "Downloaded manifest is empty, keeping previous cache"
rm -f "$manifest_cache.tmp"
return 0
fi4. jq Error Handling (Medium)Location: Issue: total_files=$(jq -r '.assets | length' "$manifest_cache" 2>/dev/null || echo "0")Recommendation: Validate JSON structure explicitly: if \! jq -e '.assets' "$manifest_cache" &>/dev/null; then
log_warn "Invalid manifest format, removing cache"
rm -f "$manifest_cache"
return 0
fi
total_files=$(jq -r '.assets | length' "$manifest_cache")5. File Download Safety (Medium-High)Location: Issue: No validation of downloaded content. A compromised GitHub account or MITM attack could inject malicious files. Current code: if curl -fsSL --connect-timeout 5 --max-time 60 "$url" -o "$local_path.tmp" 2>/dev/null; then
mv "$local_path.tmp" "$local_path"Recommendations:
6. Docker Workflow - Manifest Creation Edge Cases (Medium)Location: Issue: Manifest creation assumes both amd64 and arm64 images were successfully pushed. If one architecture fails silently, Recommendation: Add existence checks before creating manifests: # Verify both architecture images exist before creating manifest
for arch_tag in "${REGISTRY}/${IMAGE_NAME}:latest-amd64" "${REGISTRY}/${IMAGE_NAME}:latest-arm64"; do
if \! docker manifest inspect "$arch_tag" &>/dev/null; then
echo "ERROR: Required image not found: $arch_tag"
exit 1
fi
done
docker manifest create "$MANIFEST_TAG" \
"${REGISTRY}/${IMAGE_NAME}:latest-amd64" \
"${REGISTRY}/${IMAGE_NAME}:latest-arm64"7. Nix Build Architecture Platform Setting (Low)Location: Issue: Recommendation: Test if this line is actually needed. If builds work without it, remove it for clarity. The QEMU action should handle platform emulation transparently. 8. Platform Detection in Template Script (Low)Location: Issue: Uses Recommendation: Use portable stat wrapper (add to beginning of file): # Platform-agnostic file size function
get_file_size() {
local file=$1
if stat -f%z "$file" &>/dev/null 2>&1; then
# macOS/BSD
stat -f%z "$file"
else
# Linux/GNU
stat -c%s "$file"
fi
}9. Missing Integration Test Checklist ItemLocation: PR description test plan Issue: Two test items are unchecked:
Recommendation: These should be tested before merge, especially the manifest creation logic which is complex and error-prone. 🔒 Security Considerations✅ Good Security Practices
|
Security improvements in template_inputs.sh: - Add path traversal validation to reject file paths containing ".." - Add file size validation (50MB limit) to prevent DoS attacks - Add file type validation using MIME type checking - Validate JSON manifest structure before processing Robustness improvements: - Capture and display actual curl error messages for debugging - Add atomic write pattern with empty file validation - Platform-agnostic file size detection (macOS/Linux compatible) - Remove unused display_name variable (shellcheck warning) CI/CD improvements in docker.yml: - Add manifest existence verification before creating multi-arch manifests - Use variables for architecture-specific tags for consistency - Add clear error messages when builds fail 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Code Review: PR #8 - Multi-arch Docker builds and auto-download template inputsOverall AssessmentThis is a well-implemented PR that adds valuable functionality. The code demonstrates strong attention to security, robustness, and error handling. I've identified several areas for consideration below. ✅ StrengthsSecurity Considerations (Excellent)
Code Quality
CI/CD Improvements
🔍 Issues & RecommendationsCritical Issues1. Missing error handling in Docker workflow manifest creation In # Line 235-237: This pulls and retags, but doesn't verify the pull succeeded
docker pull "$CUDA_AMD64_TAG"
docker tag "$CUDA_AMD64_TAG" "$CUDA_TAG"
docker push "$CUDA_TAG"Recommendation: Add error checking after the pull: if ! docker pull "$CUDA_AMD64_TAG"; then
echo "ERROR: Failed to pull CUDA image"
exit 1
fiSecurity Concerns2. Path traversal check is incomplete (Medium severity)
if [[ "$file_path" =~ \.\. ]]; thenThis won't catch encoded variations like Recommendation: Use a more robust check: # Get the absolute canonical path
local canonical_path
canonical_path=$(readlink -f "$input_dir/$filename" 2>/dev/null || echo "")
# Check if it's within the input directory
if [[ ! "$canonical_path" =~ ^"$input_dir"/ ]]; then
log_warn "File path escapes input directory: $file_path"
((fail_count++))
continue
fi3. URL validation missing
Recommendation: Add URL scheme validation: # Validate URL uses HTTPS
if [[ ! "$url" =~ ^https:// ]]; then
log_warn "Skipping non-HTTPS URL: $url"
((fail_count++))
continue
fiPerformance Considerations4. Sequential file downloads Lines 87-164 in Recommendation: Consider parallel downloads with a concurrency limit: # Use background jobs with a limit
max_parallel=5
while read -r line; do
# ... download logic ...
download_file "$url" "$local_path" &
# Wait if we hit max parallel
if ((++job_count % max_parallel == 0)); then
wait
fi
done
wait # Wait for remaining jobs5. Inefficient file counting in Line 208 uses file_count=$(find "$input_dir" -maxdepth 1 -type f ! -name ".*" 2>/dev/null | wc -l)Recommendation: Use a more efficient approach: # Count files directly with shell globbing
shopt -s nullglob
files=("$input_dir"/*)
file_count=${#files[@]}Code Quality6. Unused variable Line 163 increments ((i++))Recommendation: Remove the unused variable. 7. Hard-coded magic number Line 209 has magic number if ((file_count < 20)); thenRecommendation: Define as a constant: MIN_EXPECTED_TEMPLATE_FILES=208. Missing Unlike other scripts in the project, Recommendation: Consider adding after the guard clause: set -euo pipefailTesting Gaps9. No tests for template_inputs.sh The PR description mentions testing the builds but doesn't mention testing the template download functionality. Recommendation: Add to test plan:
10. Multi-arch builds not fully tested Test plan shows checkboxes for building but: - [ ] CI workflow builds and pushes all variants
- [ ] Template input files download correctly on first launchThese critical items are unchecked. Recommendation: Complete testing before merge, especially:
Documentation11. Missing failure scenarios in README The README updates don't mention what happens when template downloads fail. Recommendation: Add a troubleshooting section: ### Troubleshooting Template Downloads
If workflow templates fail to load, template input files may be missing. To manually download:
```bash
# Check logs for download errors
$BASE_DIR/input/.template_manifest.jsonMinor Issues12. Inconsistent error message format Some error messages end with periods, others don't. Be consistent. 13. Docker workflow could benefit from caching The multi-arch builds rebuild everything. Consider using Docker layer caching with 📊 Performance Impact
🔒 Security Summary
📝 Recommendations SummaryMust Fix Before Merge
Should Fix
Nice to Have
🎯 ConclusionThis PR adds significant value by enabling Apple Silicon support and auto-downloading template files. The code quality is generally high with good security practices. However, I recommend addressing the critical security issues and completing the testing before merge. Recommendation: Request changes for items 1-4, then approve after fixes. Review conducted by Claude Code - focus areas: security, performance, code quality, CI/CD |
Security improvements: - Add error handling for docker pull in CUDA manifest creation - Improve path traversal validation with canonical path check - Add HTTPS URL scheme validation for downloads - Check for absolute paths and .. in filenames Code quality: - Remove unused variable 'i' in download loop - Add MIN_EXPECTED_TEMPLATE_FILES constant (was magic number 20) These changes address the "Must Fix" and "Should Fix" items from the code review on PR #8.
* fix: Address code review security and robustness concerns Security improvements: - Add error handling for docker pull in CUDA manifest creation - Improve path traversal validation with canonical path check - Add HTTPS URL scheme validation for downloads - Check for absolute paths and .. in filenames Code quality: - Remove unused variable 'i' in download loop - Add MIN_EXPECTED_TEMPLATE_FILES constant (was magic number 20) These changes address the "Must Fix" and "Should Fix" items from the code review on PR #8. * fix: Address follow-up code review feedback - Remove realpath dependency for cross-platform compatibility (macOS) - Simplify path validation condition (remove redundant regex check) - Add error handling for docker tag and push operations
Summary
This PR adds two significant enhancements to the project:
amd64(x86_64) andarm64(aarch64/Apple Silicon)Multi-Architecture Docker Support
linux/amd64andlinux/arm64platformslinux/amd64only (NVIDIA CUDA requirement)docker/setup-qemu-actionfor cross-platform buildsdocker pullwithout specifying architectureThis enables Apple Silicon Mac users to run ComfyUI in Docker without Rosetta emulation overhead.
Template Input Files Auto-Download
Workflow templates reference example input images (e.g.,
example.png,city_snow.png) that aren't bundled with the ComfyUI package. These are hosted on GitHub and need to be downloaded separately.New
scripts/template_inputs.sh:Comfy-Org/workflow_templatesrepository$BASE_DIR/input/Runtime dependencies:
curlandjqto PATH viamakeWrapperjqto Docker imagesChanges
.github/workflows/docker.ymlflake.nixmakeWrapperwith curl/jq, added jq to Docker imagesscripts/template_inputs.shscripts/install.shREADME.mdCLAUDE.mdDocker Tags After This PR
latestlatest-cudaX.Y.ZX.Y.Z-cudaTest Plan
nix flake checkpasses all checks (shellcheck, ruff, pyright, nixfmt)nix build .#packages.x86_64-linux.dockerImagebuilds successfully (amd64)nix build .#packages.x86_64-linux.dockerImageCudabuilds successfully (amd64)nix build .#packages.aarch64-linux.dockerImagebuilds successfully (arm64)manifest.jsoninspection🤖 Generated with Claude Code